package com.example.controller;

import cn.hutool.core.bean.BeanUtil;
import com.example.DTO.LoginFormDTO;
import com.example.DTO.UserDTO;
import com.example.common.Result;
import com.example.domain.User;
import com.example.service.UserService;
import com.example.utils.RegexUtils;
import com.example.utils.UserHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import static com.example.common.RedisContants.LOGIN_CODE_KEY;
import static com.example.common.RedisContants.LOGIN_USER_KEY;


@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {


    @Resource
    private UserService userService;

    @Resource
    public StringRedisTemplate stringRedisTemplate;

    /**
     * 发送验证码
     *
     * @param phone
     * @param request
     * @return
     */
    @GetMapping("/code")
    public Result SendCode(String phone, HttpServletRequest request) {
        //1、校验手机号是否合法
        if (!RegexUtils.isPhoneInvalid(phone)) {
            return Result.fail("验证码格式异常");
        }
        Result code = userService.sendCode(phone, request);
        return code;
    }

    /**
     * 基于session实现用户登陆注册
     *
     * @param loginFormDTO
     * @param request
     * @return
     */
    @PostMapping("/sessionlogin")
    public Result<UserDTO> SessionLogin(LoginFormDTO loginFormDTO, HttpServletRequest request) {
        //1、首先校验手机号和验证码是否合法
        String phone = loginFormDTO.getPhone();
        if (!RegexUtils.isPhoneInvalid(phone)) {
            return Result.fail("手机号格式异常！");
        }

        Result sessionLogin = userService.SessionLogin(loginFormDTO, request);
        if (sessionLogin == null) {
            return Result.fail("用户信息不存在！");
        }
        return sessionLogin;
    }

    @PostMapping("/redislogin")
    public Result<UserDTO> RedisLogin(LoginFormDTO loginFormDTO, HttpSession session) {
        //1、首先校验手机号和验证码是否合法
        String phone = loginFormDTO.getPhone();
        if (!RegexUtils.isPhoneInvalid(phone)) {
            return Result.fail("手机号格式异常！");
        }

        Result result = userService.RedisLogin(loginFormDTO, session);
        if (result == null) {
            return Result.fail("用户信息不存在！");
        }
        //删除验证码
        stringRedisTemplate.delete(LOGIN_CODE_KEY + phone);
        return result;
    }

    /**
     * 获取当前登录用户
     *
     * @return
     */
    @GetMapping("/loginuser")
    public Result<UserDTO> loginuser(HttpServletRequest request) {
        //Object attribute = request.getSession().getAttribute("user");
        //UserDTO user = (UserDTO) attribute;
        UserDTO user = UserHolder.getUser();
        //判断user是否为空
        if (user == null) {
            log.debug("用户登录状态失效了！");
            return Result.fail("用户登录状态失效了！");
        }
        return Result.ok(user);
    }

    /**
     * 用户注销
     *
     * @param request
     * @return
     */
    @GetMapping("/logout")
    public Result logout(HttpServletRequest request) {
        String token = request.getHeader("authorization");
        String tokeKey = LOGIN_USER_KEY + token;
        stringRedisTemplate.delete(tokeKey);
        //request.getSession().removeAttribute("user");
        //TODO 不知为何这段代码不行
        //UserHolder.removeUser();
        log.debug("用户退出登录成功！");
        return Result.ok("用户退出登录成功！");
    }

    /**
     * 根据id查询用户信息
     *
     * @param userId
     * @return
     */
    @GetMapping("/{id}")
    public Result queryUserById(@PathVariable("id") Long userId) {
        // 查询详情
        User user = userService.getById(userId);
        if (user == null) {
            return Result.ok();
        }
        UserDTO userDTO = BeanUtil.copyProperties(user, UserDTO.class);
        // 返回
        return Result.ok(userDTO);
    }

    /**
     * 用户签到功能
     *
     * @return
     */
    @PostMapping("/sign")
    public Result sign() {
        return userService.sign();
    }

    /**
     * 查询用户连续签到次数
     *
     * @return
     */
    @GetMapping("/sign/count")
    public Result signCount() {
        return userService.signCount();
    }
}
